package cn.edu.thu.laud.thrift;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.edu.thu.laud.com.utils.IOUtils;
import cn.edu.thu.laud.thrift.service.DataTransferService;
import cn.edu.thu.laud.thrift.service.LaUDClientState;
/**
 * 
 * Simple class to run the data(file) connection accepting code in separate
 * thread of control.
 *
 * 
 *
 */
public class LaUDDataServer extends Thread{

	private ServerSocket fileServer;
	public static ExecutorService execService;
	static Logger logger = LoggerFactory.getLogger(LaUDDataServer.class);
	/**
	 * key:sessionid
	 * value:laud's clientState
	 */
	public static ConcurrentHashMap<String, LaUDClientState> authorizedUsers=new ConcurrentHashMap<String, LaUDClientState>();

	private int defaultSystemThreadNumber=200;
	public LaUDDataServer(InetAddress listenAddr, int listenPort) throws  UnknownHostException, IOException
	{	
		if(fileServer==null){
			fileServer= new ServerSocket(listenPort, 0, listenAddr);
		}
		logger.info(String.format("Binding data service to %s:%s", listenAddr, listenPort));

		this.
		defaultSystemThreadNumber=Integer.parseInt(LaUDLogUtils.parser.getElementString("DataThreadNumber",defaultSystemThreadNumber));
		execService = Executors.newFixedThreadPool(defaultSystemThreadNumber);
	}

	public void setAuthorizedUsers(ConcurrentHashMap<String, LaUDClientState> authorizedUsers) {
		LaUDDataServer.authorizedUsers=authorizedUsers;
	}
	public void run()
	{
		while (true) {
			Socket socket = null;
			try {
				socket = fileServer.accept();
				logger.info("a data transfer connection started...\r\n");
				DataTransferService dataTransferService = new DataTransferService(socket);
				// controlSrv.testMultiUser();
				execService.execute(dataTransferService);

				System.out.print("Current number of threads#"
						+ Thread.activeCount() + ":");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				IOUtils.close(socket);
				socket = null;
			} 
		}
	}

	public void stopServer()
	{
		logger.info("Stop listening to thrift clients....");
		try {
			this.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if(!fileServer.isClosed()){
			try {
				fileServer.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		logger.info("Stoped!\r\n");
	}
}
